package GUI;

import Control.Shape;
import Control.Shape.Shapes;
import Control.UFO;

import com.modestmaps.core.Point2f;
import com.modestmaps.geo.Location;

public class Cluster {

	private int gridSize;                   // The size of each cluster
	private int numberOfGridsX;              // How many clusters this grid has in the X Axis  
	private int numberOfGridsY;              // How many clusters this grid has in the X Axis
	private int[][] dataInEachGrid; //

	private float[][] angles;
	private Point2f[] centers;
	private boolean draw =false;

	public Cluster () {
		this.gridSize = GV.mapClass.map.TILE_HEIGHT;
		numberOfGridsX = (int) (GV.mapClass.map.width/GV.mapClass.map.TILE_WIDTH);
		numberOfGridsY = (int) (GV.mapClass.map.height/GV.mapClass.map.TILE_HEIGHT);

		if( GV.mapClass.map.width % GV.mapClass.map.TILE_WIDTH != 0) numberOfGridsX++;
		if( GV.mapClass.map.height % GV.mapClass.map.TILE_HEIGHT != 0) numberOfGridsY++;

		dataInEachGrid = new int[numberOfGridsX * numberOfGridsY][4];    
	}

	public void draw() {
		if(!draw)return;
		GV.processing.fill(GV.backGroundColor);
		GV.processing.strokeWeight(2);
		for(int i=0;i<numberOfGridsX;i++){
			GV.processing.line(i*gridSize, 0, i*gridSize, GV.height);
		}
		for(int j=0;j<numberOfGridsY;j++){
			GV.processing.line(0,j*gridSize, GV.width, j*gridSize);

		}

		for(int i=0;i<dataInEachGrid.length;i++){
			piechart(gridSize/2, angles[i], GV.colors,centers[i]);
		}
		drawPieHighLight();
	}

	public void createGridData(){
		if(GV.ufoToDisplay.size()<1){draw=false;return;}
		dataInEachGrid = new int[numberOfGridsX * numberOfGridsY][4];

		if(GV.shapeCategoryColor){
			for(UFO u :GV.ufoToDisplay){
				Point2f p = GV.mapClass.map.locationPoint(new Location(u.getCoordinates().x, u.getCoordinates().y));
				int colIndex = GV.getColorIndex(u.getShape().shape.ordinal());
				addData(p.x, p.y, colIndex);
			}	
		}
		else{
			for(UFO u :GV.ufoToDisplay){
				Point2f p = GV.mapClass.map.locationPoint(new Location(u.getCoordinates().x, u.getCoordinates().y));
				addData(p.x, p.y, u.getShape().getCategory().ordinal());
			}	
		}

		angles = new float[numberOfGridsX * numberOfGridsY][4];
		centers = new Point2f[numberOfGridsX * numberOfGridsY];
		for(int i=0;i<dataInEachGrid.length;i++){
			int total=0;
			for(int j=0;j<dataInEachGrid[i].length;j++){
				total += dataInEachGrid[i][j];
			}
			float sum = 0; int j=0;
			for(j=0;j<dataInEachGrid[i].length-1;j++){
				float val = dataInEachGrid[i][j]/(float)total;
				angles[i][j] = GV.processing.map(val, 0, 1, 0, 360);
				sum+=val;
			}
			angles[i][j] = GV.processing.map(1-sum, 0, 1, 0, 360);
			float xGrid = i%numberOfGridsX;
			float yGrid = i/numberOfGridsX;
			float yPos;
			if(yGrid==0){yPos = gridSize/(float)1.5; }
			else if(yGrid==2){yPos = (yGrid)*gridSize+gridSize/(float)3;}
			else yPos = (yGrid)*gridSize+gridSize/2; 
			float xPos = (xGrid)*gridSize+gridSize/2; 


			centers[i] = new Point2f(xPos,yPos);
		}

		draw=true;
	}

	public void addData(float x, float y,int colorVal) {
		if( x > 0 && y > 0 && x < GV.mapClass.map.width && y < GV.mapClass.map.height ) {
			int xGrid = (int) (x / gridSize);
			int yGrid = (int) (y / gridSize);
			try {
				//System.out.println(xGrid+" "+yGrid+" "+((yGrid) * numberOfGridsX + (xGrid)));
				dataInEachGrid[(yGrid) * numberOfGridsX + (xGrid)][colorVal]++;
			}
			catch(Exception e) {
				System.out.println("X: " + x + " Y: " + y);
				System.out.println("xGrid: " + xGrid + " yGrid: " + yGrid);

			}
		}//else{System.out.println("Point discarded "+x+" "+y);}
	}


	public void piechart(int diameter,float[] angs,int[] colors,Point2f p){

		GV.processing.noStroke();

		float lastAng = 0;

		for (int i = 0; i < angs.length; i++){
			GV.processing.fill(colors[i],140);
			GV.processing.arc(p.x, p.y, diameter, diameter, lastAng, lastAng+GV.processing.radians(angs[i]));
			lastAng += GV.processing.radians(angs[i]);  
		}
	}



	private void drawPieHighLight(){
		int diameter = gridSize/2;
		for(int i=0;i<dataInEachGrid.length;i++){	
			float[] angs = angles[i];
			Point2f p = centers[i];
			float lastAng=0;
			float dist =GV.processing.dist(p.x, p.y, GV.processing.mouseX, GV.processing.mouseY);
			if(dist<=diameter/2){
				float dy = GV.processing.mouseY-p.y;
				float dx = GV.processing.mouseX-p.x;
				float mouseAngle = (float) Math.atan2(dy,dx);
				if(dy<0)
					mouseAngle = GV.processing.abs(mouseAngle);
				else mouseAngle = 2*GV.processing.PI-mouseAngle;
				mouseAngle = 2*GV.processing.PI - mouseAngle;
				for (int j = 0; j < angs.length; j++){
					float newAngle = lastAng + GV.processing.radians(angs[j]);
					if(mouseAngle>lastAng && mouseAngle<newAngle){
						
						//System.out.println("mouse Angle "+ mouseAngle +"  lastAng "+lastAng+"  newAngle  "+newAngle);
						//System.out.println("Angolo "+angs[j]+"  Angolo radianti"+GV.processing.radians(angs[j]));
						GV.processing.strokeWeight(2);
						GV.processing.rectMode(GV.processing.CORNER);
						GV.processing.fill(GV.backGroundColor);
						GV.processing.stroke(80);
						GV.processing.rect(GV.processing.mouseX+5,GV.processing.mouseY,125,20);
						GV.processing.textAlign(GV.processing.LEFT);
						GV.processing.fill(GV.textColor);
						GV.processing.text((int)((GV.processing.radians(angs[j])/(2*GV.processing.PI)*100)+0.5)+"%",GV.processing.mouseX+5+80,GV.processing.mouseY+15);
						//GV.processing.text("color "+j,p.x+10,p.y+10);
						
						int [] shCol = new int[4];int count=0;
						if(GV.shapeCategoryColor){
							for(int k=0;k<GV.shapes.size();k++){
								for(int z=0;z<GV.shapesSelected.size();z++)
								if(GV.shapesSelected.get(z).shape.ordinal()==GV.shapes.get(k).shape.ordinal()){
									shCol[count]=GV.shapesSelected.get(z).shape.ordinal();
									count++;
									if(count==4)break;
								}
							}
							GV.processing.text(GV.shapes.get(shCol[j]).name,GV.processing.mouseX+5+10,GV.processing.mouseY+15);
								
							
						}
						else{
							if(j==Shape.Category.CIRCULAR.ordinal())
							GV.processing.text("Circular",GV.processing.mouseX+5+10,GV.processing.mouseY+15);
							else if(j==Shape.Category.POLYGONAL.ordinal())
								GV.processing.text("Polygonal",GV.processing.mouseX+5+10,GV.processing.mouseY+15);
							if(j==Shape.Category.LIGHT.ordinal())
								GV.processing.text("Light Fire",GV.processing.mouseX+5+10,GV.processing.mouseY+15);
							if(j==Shape.Category.OTHER.ordinal())
								GV.processing.text("Other",GV.processing.mouseX+5+10,GV.processing.mouseY+15);

						}
						
					}
					lastAng += GV.processing.radians(angs[j]);  
				}
			}
		}
	}


}